立创梁山派GD32F470ZGT6 |
您所在的位置:网站首页 › gd32 uart dma › 立创梁山派GD32F470ZGT6 |
准备
屏幕 使用SPI接口的1.69寸240x280TFT彩屏. 主控 使用立创·梁山派GD32F470ZGT6. 屏幕与主控的连接 使用硬件SPI+DMA的方式刷屏。 一般我们拿到一个屏幕首先需要移植厂商提供的官方代码进行亮屏测试。这里我们就不使用DMA配置了,只用最基本Io模拟SPI或者硬件SPI的方法,先将屏幕点亮清屏或者整屏刷新颜色就行。 移植好代码后要仔细观察颜色刷新是否正确(色差),显示方法是否正确(横屏竖屏),颜色数据刷新是否正常(错,漏,闪烁)。 设计连线符合器件要求无误的情况下存在问题,就需要查看手册,通过手册发现GD32F470的SPI存在FIFO,所以发送数据的结尾需要等待数据发送完成再释放片选。否则容易导致屏幕显示出现问题(一般都是以缓冲区是否为空当作传输的判断标准,以此提高发送效率)。 需要使能硬件SPI的DMA发送功能。 void lcd_gpio_config(void) { spi_parameter_struct spi_init_struct; rcu_periph_clock_enable(RCU_LCD_SCL); rcu_periph_clock_enable(RCU_LCD_SDA); rcu_periph_clock_enable(RCU_LCD_CS); rcu_periph_clock_enable(RCU_LCD_DC); rcu_periph_clock_enable(RCU_LCD_RES); rcu_periph_clock_enable(RCU_LCD_BLK); rcu_periph_clock_enable(RCU_SPI_HARDWARE); // 使能SPI /* 配置 SPI的SCK GPIO */ gpio_af_set(PORT_LCD_SCL, LINE_AF_SPI, GPIO_LCD_SCL); gpio_mode_set(PORT_LCD_SCL, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_LCD_SCL); gpio_output_options_set(PORT_LCD_SCL, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_SCL); gpio_bit_set(PORT_LCD_SCL,GPIO_LCD_SCL); /* 配置 SPI的MOSI GPIO */ gpio_af_set(PORT_LCD_SDA, LINE_AF_SPI, GPIO_LCD_SDA); gpio_mode_set(PORT_LCD_SDA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_LCD_SDA); gpio_output_options_set(PORT_LCD_SDA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_SDA); gpio_bit_set(PORT_LCD_SDA, GPIO_LCD_SDA); /* 配置DC */ gpio_mode_set(PORT_LCD_DC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DC); gpio_output_options_set(PORT_LCD_DC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_DC); gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET); /* 配置RES */ gpio_mode_set(PORT_LCD_RES,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_RES); gpio_output_options_set(PORT_LCD_RES,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_RES); gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET); /* 配置BLK */ gpio_mode_set(PORT_LCD_BLK, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_LCD_BLK); gpio_output_options_set(PORT_LCD_BLK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_BLK); gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, SET); /* 配置CS */ gpio_mode_set(PORT_LCD_CS,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_LCD_CS); gpio_output_options_set(PORT_LCD_CS,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_CS); gpio_bit_write(PORT_LCD_CS, GPIO_LCD_CS, SET); // 配置 SPI 参数 spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;// 传输模式全双工 spi_init_struct.device_mode = SPI_MASTER; // 配置为主机 spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; // 8位数据 spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; // 极性高相位2 spi_init_struct.nss = SPI_NSS_SOFT; // 软件cs spi_init_struct.prescale = SPI_PSC_2; // 2分频 spi_init_struct.endian = SPI_ENDIAN_MSB; // 高位在前 spi_init(PORT_SPI, &spi_init_struct); //使能DMA发送 spi_dma_enable(PORT_SPI,SPI_DMA_TRANSMIT); // 使能 SPI spi_enable(PORT_SPI); //初始化DMA dma_spi_init(); } 配置DMA使用DMA的通用流程都是先配置外设对应的DMA及通道,再配置自动或者软件触发DMA搬运方向。不过,我们需要根据屏幕的像素确定要传输的数据量,DMA的最大数据传输量为65535。而我使用的是1.69寸屏幕,像素为240x280,即全部像素为240 * 280 = 67200,已经超过了最大DMA传输量。所以将全部像素数据分两次进行传输,即67200 / 2 = 33600。但是,我的数据宽度设置为了8位,即一次传输8位的数据。而我使用的1.69寸屏,是TFT彩屏,一个像素点需要16位的彩色数据。DMA设置为8位传输,而屏幕一个像素是16位的数据,故实际的传输数据量为全部像素大小*2!即67200 * 2=134400。所以我们想要显示一帧图像,需要传输4次! DMA初始化配置后,需要再次传输的快捷操作为:清除标志位,设置传输量,设置传输地址,开始传输。 关于清除全部中断标志位的解释 因为我使用到的硬件SPI的是DMA1的通道3,实际上只需要往DMA_INTC0寄存器写入( 0x2f |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |